package org.midy.infrastructure;

import org.midy.infrastructure.tools.CloseHandler;
import org.midy.infrastructure.tools.Logger;

import java.io.IOException;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;

public class AcceptEventHandler implements EventHandler {
    private final EventDrivenTaskAllocation eventDrivenTaskAllocation;

    public AcceptEventHandler(EventDrivenTaskAllocation eventDrivenTaskAllocation) {
        this.eventDrivenTaskAllocation = eventDrivenTaskAllocation;
    }

    @Override
    public Object handle(SelectionKey selectionKey) {
        if (!selectionKey.isValid()) {
            return false;
        }

        ServerSocketChannel server = (ServerSocketChannel) selectionKey.channel();
        SocketChannel socketChannel = null;

        try {
            while ((socketChannel = server.accept()) != null) { //是否存在多个请求建立连接的
                socketChannel.configureBlocking(false);
                socketChannel.socket().setKeepAlive(true);
                try {
                    if (socketChannel.isConnected() || socketChannel.finishConnect()) {
                        Logger.info("[新连接] IP:PORT[%s] 正在处理中 ... ", socketChannel.getRemoteAddress().toString());
                        boolean allocation = eventDrivenTaskAllocation.allocation(socketChannel, SelectionKey.OP_READ);
                        if (allocation) {
                            Logger.info("[新连接] IP:PORT[%s], 分派成功！", socketChannel.getRemoteAddress().toString());
                        } else {
                            Logger.info("[新连接] IP:PORT[%s], 分派失败！",socketChannel.getRemoteAddress().toString());
                            if (socketChannel.isOpen()) {
                                CloseHandler.closeSocketChannel(socketChannel);
                            }
                        }
                    } else if (socketChannel.isConnectionPending()) {
                        socketChannel.register(selectionKey.selector(), SelectionKey.OP_CONNECT);
                        Logger.info("[新连接] IP:PORT[%s], 正在连接中 ... ", socketChannel.getRemoteAddress().toString());
                    } else {
                        Logger.warn("[新连接] IP:PORT[%s], 建立连接失败 ", socketChannel.getRemoteAddress().toString());
                        CloseHandler.closeSocketChannel(socketChannel);
                    }
                } catch (IOException e) {
                    Logger.error("[新连接] 处理失败", e);
                    CloseHandler.closeSocketChannel(socketChannel);
                }
            }
        } catch (Throwable t) {
            Logger.error("处理新连接事件失败", t);
            throw new RuntimeException("ServerSocketChannel is error");
        }

        return true;
    }
}
